package com.financing.controller.user;
import java.util.Date;
import java.util.Map;

import com.financing.common.CONST;
import com.financing.components.payment.Gateway;
import com.financing.components.sms.Sms;
import com.financing.enums.invest.InvestLogType;
import com.financing.enums.notify.AgentNotify;
import com.financing.enums.notify.AssetsNotify;
import com.financing.enums.notify.SmsNotify;
import com.financing.model.Data;
import com.financing.model.invest.Withdraw;
import com.financing.model.user.User;
import com.financing.service.invest.InvestLogService;
import com.financing.service.system.AssetsLogService;
import com.financing.service.system.LoggerService;
import com.financing.service.user.WithdrawService;
import com.financing.util.DateUtil;
import com.financing.util.Json;
import com.financing.util.Str;
import com.financing.util.XmlHelper;
import com.jfinal.aop.Clear;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Page;

/**
 * 提现控制器
 * @author 无处不在的二叔
 */
public class WithdrawController extends Controller {
	private LoggerService log = new LoggerService();
	private WithdrawService withdraw = new WithdrawService();	
	private AssetsLogService assetsLog = new AssetsLogService();	
	
	/**
	 * 提现
	 */
	public void index1() throws Exception {
		User u = getAttr("user");
		double amount = Double.valueOf(getPara("amount")); 
		String type = getPara("type","app"); 
		
		// 检查用户是否绑定银行卡
		if(u.getIsBindBankCard()==1){ 
			// Gateway.托管充值 
			String code = DateUtil.getTimeStamp();				
			// 剩余可免费提现次数 
			/** long count = withdraw.countInMonth(u.getId());
			double userFee = 0;//Double.valueOf(count>=CONST.WITHDRAW_FREE_COUNT ? CONST.find("WITHDRAW_USER_FEE") : "0");
			if(userFee>0) {
				amount = Money.safeSub(Double.valueOf(amount), Double.valueOf(userFee));
			}*/
			
			if(Double.valueOf(amount)>0) {
				Map<Object, Object> data = Gateway.form(Str.eq("app", type)?"/app/500003":"/500003", Data.put(
					"mchnt_txn_ssn",code,
					"login_id",u.getCode(),
					"amt",Double.valueOf(amount*100).intValue(),
					"page_notify_url",CONST.URL+"/app/page/user-return", 
					"back_notify_url",CONST.URL+"/withdraw/toNotify",
					"sign","amt,back_notify_url,login_id,mchnt_cd,mchnt_txn_ssn,page_notify_url"
				));
				
				Withdraw w = new Withdraw(); 
				w.setUserId(u.getId());
				w.setCode(code);
				w.setAmount(amount);
				w.setCreateTime(new Date());
				w.setStatus("init"); 
				w.setMobile(u.getMobile());
				w.setRealName(u.getRealName());
				w.setSummary("发起提现申请");
				w.setUserFee(0.0);
				w.setPlatFee(Double.valueOf(CONST.find("WITHDRAW_PLAT_FEE")));
				w.save();		
				System.out.println("url==="+data.get("url"));
				setAttr("data", data);
				render("/view/app/user/withdraw.html");
			}else{
				renderJson(Json.error("提现金额不可小于0！"));
			}
		}else{
			renderJson(Json.error("您未实名绑卡！"));
		}
	}	

	/**
	 * 提现异步回调
	 * @throws Exception 
	 */
	@Clear
	public void toNotify() throws Exception {
		String type = getPara("resp_code");
		String summary = getPara("resp_desc");
		String code = getPara("mchnt_txn_ssn");
		Withdraw w = withdraw.findByCode(code);
		User u = User.me.findById(w.getUserId());
		String date = DateUtil.format(w.getCreateTime(), DateUtil.DATE_LOCAL_FORMAT);
		
		if(Str.eq("0000", type)) {

			// 修改提现记录状态
			w.setStatus("success").setSummary("提现申请成功").update();
			
			// 插入提现交易记录
			InvestLogService.build("提现", InvestLogType.WITHDRAW, w.getId(), w.getAmount(), w.getUserId(), "success", "提现申请成功", code);
			
			// 插入财务记录
			// FinanceLogService.build(User.me.findById(1), null, 2.0, w.getCode(), FinanceLogType.WITHDRAW_FEE, u.getRealName()+"提现手续费");
			
			// 扣除并记录提现手续费
			if(w.getUserFee()>0){
				XmlHelper res = Gateway.pay(u.getCode(), CONST.PLAT_CODE, w.getUserFee(), u.getRealName()+"提现手续费"+w.getUserFee()+"元",true,false);
				if(res.isSuccess()) {
					InvestLogService.build("提现手续费",InvestLogType.WITHDRAW_FEE, w.getId(), w.getUserFee(), w.getUserId(), "success", "提现手续费", code);
				}
			}
			
			// 插入资产记录-提现成功
			AssetsNotify notify = AssetsNotify.WITHDRAW_PROCESS;
			AgentNotify agentNotify = AgentNotify.WITHDRAW_PROCESS;
			assetsLog.bulid(u, notify.getName(), Str.format(notify.getContents(), date, CONST.find("PLAT_PHONE")), 
				Str.format(agentNotify.getContents(), u.getMobile()+"（"+u.getRealName()+"）", date, w.getAmount(), u.getAvailableAmount()));

			log.build("提现", "用户发起提现"+w.getAmount()+"元", u.getId(), "user");
			
			// 发送提现发起成功短信提醒 
			Sms.send(u.getMobile(), Str.format(SmsNotify.WITHDRAW_PROCESS, date, CONST.find("PLAT_PHONE")));

		}else {
			// 更新状态
			w.setStatus("failed").setSummary(summary).update();

			// 插入提现交易记录
			InvestLogService.failed(InvestLogType.WITHDRAW.getType(), w.getId(), summary);
			
			// 插入提现手续费
			if(w.getUserFee()>0){
				InvestLogService.failed(InvestLogType.WITHDRAW_FEE.getType(), w.getId(), summary);
			}
			
			// 插入资产记录-提现失败
			AssetsNotify notify = AssetsNotify.WITHDRAW_FAILED;
			AgentNotify agentNotify = AgentNotify.WITHDRAW_FAILED;
			assetsLog.bulid(u, notify.getName(), Str.format(notify.getContents(), date, CONST.find("PLAT_PHONE")), Str.format(agentNotify.getContents(), u.getMobile()+"（"+u.getRealName()+"）", date, w.getAmount(), u.getAvailableAmount()));

			// 发送提现失败短信提醒
			// Sms.send(u.getMobile(), Str.format(SmsNotify.WITHDRAW_FAILED, date, CONST.find("PLAT_PHONE")));
			
			// 日志记录
			log.build("提现", "用户提现失败，原因："+summary, u.getId(), "user");
		}
		renderHtml(Gateway.response(code));
	}

	/**
	 * 提现退票通知
	 * @throws Exception 
	 */
	@Clear
	public void refundNotify() throws Exception {
		
		String code = getPara("mchnt_txn_ssn");
		String remark = getPara("remark");
		Withdraw w = withdraw.findByCode(code);
		String date = DateUtil.format(w.getCreateTime(), DateUtil.DATE_LOCAL_FORMAT);
		User u = User.me.findById(w.getUserId());

		// 更新状态
		w.setStatus("failed").setSummary(remark).update();

		// 插入提现交易记录
		InvestLogService.failed(InvestLogType.WITHDRAW.getType(), w.getId(), remark);
		
		// 插入资产记录-提现失败
		AssetsNotify notify = AssetsNotify.WITHDRAW_FAILED;
		AgentNotify agentNotify = AgentNotify.WITHDRAW_FAILED;
		assetsLog.bulid(u, notify.getName(), Str.format(notify.getContents(), date, CONST.find("PLAT_PHONE")), Str.format(agentNotify.getContents(), u.getMobile()+"（"+u.getRealName()+"）", date, w.getAmount(), u.getAvailableAmount()));

		// 日志记录
		log.build("提现", "用户提现失败，原因："+remark, u.getId(), "user");
	
		renderJson("SUCCESS");
	}
	
	/**
	 * 提现列表
	 */
	public void list() { 
		int page = getParaToInt("page",1);
		int size = getParaToInt("size",10);
		Map<String,String> params = Data.flat(getParaMap());
		Page<Withdraw> p = withdraw.list(page,size,params);
		for(Withdraw w : p.getList()) {
			w.put("user", User.me.findById(w.getUserId()));
		}
		// 计算总充值金额
		params.put("status", "success");
		double total = withdraw.sumByParams(params);
		
		// 计算总充值人数
		double success_count = withdraw.countByParams(params);
		params.remove("status");
		double total_count= withdraw.countByParams(params);
		
		renderJson(Json.ok("数据获取成功！", Data.put("total_count",total_count, "success_count",success_count, "total",total, "page",p)));
	}
} 
 